home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir24
/
psi110g.zip
/
BPQ.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-17
|
10KB
|
377 lines
/* code to allow nos to talk directly to bpqcode
*
* by paul h launspach n5faz
* (c) 1993,1994 FazCom
* 4-13-93
*/
/* $Id: bpq.c 1.4 1994/03/11 14:46:16 fz-phl Exp $ */
/* $Log: bpq.c $
* Revision 1.4 1994/03/11 14:46:16 fz-phl
* added ifdef BPQJNOS for printf -> tprintf macro and
* for different dump and net_route calls.
*
* Revision 1.3 1994/03/11 14:36:32 Johan
* changed printf's to tprintf's
*
* Revision 1.2 1994/03/11 14:29:02 fz-phl
* added ifdef BPQSOCK and changed dump and netroute
* calls for jnos.
*
* Revision 1.1 1994/03/11 02:24:15 fz-phl
* Initial revision
*
*/
#include <stdio.h>
#include <dos.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "iface.h"
#include "trace.h"
#include "pktdrvr.h"
#include "config.h"
#ifdef BPQ
#include "bpq.h"
#ifdef BPQJNOS /* change printf to tprintf for jnos etc */
#define printf tprintf
#endif
static int bpq_stop (struct iface *iface);
static int bpq_raw (struct iface *iface, struct mbuf *bp);
struct bpqinfo Bpqinfo = {0};
extern int32 Ip_addr;
/* attach an interface to bpqcode
*
* init bpq:
* argv[0] = bpq
* argv[1] = init
* argv[2] = bpq_host intrupt vec in hex
* argv[3] = bpq_host stream number
* argv[4] = number of outgoing bpq_host sessions optional
*
* attach an iface:
* argv[0] = bpq
* argv[1] = bpq radio port number
* argv[2] = lable
* argv[3] = mtu optional
* argv[4] = callsign optional
*
*/
int
bpq_attach(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char vec;
char streem;
int port;
int users = 0;
uint16 mtu;
char hwaddr[AXALEN];
struct iface *ifp;
char *cp;
char buffer[6];
static char g8bpq[] = "G8BPQ";
if(strncmp(argv[1],"init",strlen(argv[1])) == 0){
if(argc < 4){
#ifdef BPQSOCK
printf("Usage: attach bpq init <vec> <stream> [<sessions>]\n");
#else
printf("Usage: attach bpq init <vec> <stream>\n");
#endif
return -1;
}
vec = htoi(argv[2]);
streem = atoi(argv[3]);
#ifdef BPQSOCK
users = argc > 4 ? atoi(argv[4]) : 0;
#endif
if(!Bpqinfo.vec){
/* check that bpqcode is loaded */
long vector = (long)getvect(vec);
movblock(FP_OFF(vector)-7, FP_SEG(vector),
FP_OFF(buffer),FP_SEG(buffer),strlen(g8bpq));
if(strncmp(buffer,g8bpq,strlen(g8bpq))){
printf("Bpqcode not found !\n");
return -1;
}
if(streem < 1 || streem > BPQMAXSTREAM){
printf("Stream must be between 1 and %d.\n",BPQMAXSTREAM);
return -1;
}
#ifdef BPQSOCK
if(users < 0 || streem + users >= BPQMAXSTREAM){
printf("Stream plus sessions must be less than %u.\n",
BPQMAXSTREAM);
return -1;
}
#endif
Bpqinfo.vec = vec;
Bpqinfo.monstream = streem;
Bpqinfo.maxstream = streem + users;
Bpqinfo.window = BPQWINDOW;
Bpqinfo.minfree = bpq_int(BPQ_BUF,1,0,NULLCHAR);
#ifdef BPQSOCK
Bpqinfo.rxproc = newproc("Bpq recieve",256,bpqrxp,0,NULL,NULL,0);
#endif
} else {
printf("Bpq already initalized");
return -1;
}
return 0;
}
if(!Bpqinfo.vec){
printf("Bpq must be initilized with: attach bpq init <vec> <stream>\n");
return 1;
}
port = atoi(argv[1]);
mtu = (argc >3) ? max(256,atoi(argv[3])) : Paclen;
if(port > BPQMAXPORT){
printf("Port must be between 1 and %d.\n",BPQMAXPORT);
return -1;
}
if(Bpqinfo.ports[port-1] != NULLIF){
printf("Port already used");
return -1;
}
if(if_lookup(argv[2]) != NULLIF){
printf("Interface %s already exists\n",argv[2]);
return -1;
}
ifp = (struct iface *)callocw(1,sizeof(struct iface));
ifp->name = strdup(argv[2]);
ifp->addr = Ip_addr;
ifp->mtu = mtu;
ifp->dev = port;
ifp->raw = bpq_raw;
ifp->stop = bpq_stop;
setencap(ifp,"AX25");
ifp->hwaddr = mallocw(AXALEN);
if(argc > 4 && setcall(hwaddr,argv[4]) == 0)
memcpy(ifp->hwaddr,hwaddr,AXALEN);
else
memcpy(ifp->hwaddr,Mycall,AXALEN);
Bpqinfo.ports[port-1] = ifp;
Bpqinfo.maxport++;
ifp->next = Ifaces;
Ifaces = ifp;
cp = if_name(ifp," tx");
#ifdef BPQSOCK
ifp->txproc = newproc(cp,768,if_tx,0,ifp,NULL,0);
#endif
/* tell bpqcode to send us any recieved frames */
bpq_int(BPQ_SET,Bpqinfo.monstream,0x80,NULLCHAR);
return 0;
}
/* detach a bpq interface
*/
static int
bpq_stop(iface)
struct iface *iface;
{
int port = iface->dev;
Bpqinfo.ports[port-1] = NULLIF;
if(--Bpqinfo.maxport == 0){
/* stop bpqcode sending us frames */
bpq_int(BPQ_SET,Bpqinfo.monstream,0,NULLCHAR);
}
return 0;
}
/* raw send
*/
static int
bpq_raw(iface,bp)
struct iface *iface;
struct mbuf *bp;
{
if(iface == NULLIF || bp == NULLBUF)
return -1;
iface->rawsndcnt++;
iface->lastsent = secclock();
if(bp->next != NULLBUF){
/* Copy to contiguous buffer */
struct mbuf *bp1 = copy_p(bp,len_p(bp));
free_p(bp);
if((bp = bp1) == NULLBUF)
return -1;
}
Bpqinfo.sendcnt++;
bpq_int(BPQ_TX,iface->dev,bp->cnt,bp->data);
free_p(bp);
return 0;
}
/* bpq raw recieve handler
* called every tick
*/
void
bpqtimer(void)
{
char port;
int txf;
/* no bpq ports in use */
if(!Bpqinfo.maxport)
return;
for(;;){
/* get a mbuf to put recieved frame in */
if(Bpqinfo.buffer == NULLBUF)
if((Bpqinfo.buffer = alloc_mbuf(BPQSIZE +
sizeof(struct iface))) == NULLBUF)
return;
else
Bpqinfo.buffer->data += sizeof(struct iface);
/* no more frames at this time so return */
if((Bpqinfo.buffer->cnt = bpq_int(BPQ_RX,Bpqinfo.monstream,0,
Bpqinfo.buffer->data)) == 0)
return;
port = Bpqinfo.buffer->data[2]; /* get port number from bpqheader */
txf =port & 0x80; /* this is a transmited frame so get another */
port &= 0x7f; /* mask off is tx frame bit */
/* recieved frame not on a port we want so get another */
if(port > BPQMAXPORT || Bpqinfo.ports[--port] == NULLIF)
continue;
Bpqinfo.buffer->data += BPQHEADER; /* move past the 5 byte */
Bpqinfo.buffer->cnt -= BPQHEADER; /* header bpq sends us */
/* trace any tx frames */
if(txf){
#ifdef BPQJNOS
dump(Bpqinfo.ports[port],IF_TRACE_OUT,CL_AX25,Bpqinfo.buffer);
#else
dump(Bpqinfo.ports[port],IF_TRACE_OUT,Bpqinfo.buffer);
#endif
continue;
}
#ifdef BPQJNOS
net_route(Bpqinfo.ports[port],CL_AX25,Bpqinfo.buffer);
#else
net_route(Bpqinfo.ports[port],Bpqinfo.buffer);
#endif
Bpqinfo.buffer = NULLBUF;
Bpqinfo.recvcnt++;
}
}
/* common interupt routine for all bpq_host calls
*/
uint16
bpq_int(command,stream,flag,bp)
char command;
char stream;
int flag;
char *bp;
{
union REGS regs;
struct SREGS sregs;
uint16 rval;
segread(&sregs);
regs.h.ah = command;
regs.h.al = stream;
switch(command){
case BPQ_SET:
case BPQ_CONNECT:
regs.h.ch = regs.h.dh = 0;
regs.h.dl = hibyte(flag); /* appl mask */
regs.h.cl = lobyte(flag); /* appl flags */
Bpqinfo.contcnt++;
break;
case BPQ_SEND:
case BPQ_TX:
regs.x.cx = flag;
sregs.es = FP_SEG(bp);
regs.x.si = FP_OFF(bp);
Bpqinfo.txcnt++;
break;
case BPQ_RECV:
case BPQ_RX:
regs.x.di = FP_OFF(bp);
sregs.es = FP_SEG(bp);
Bpqinfo.rxcnt++;
break;
case BPQ_BUF:
case BPQ_UNACK:
case BPQ_RECVQUE:
regs.h.ah = BPQ_BUF;
Bpqinfo.contcnt++;
break;
case BPQ_USERCALL:
case BPQ_PACLEN:
case BPQ_MAXFR:
regs.h.ah = BPQ_USERCALL;
sregs.es = FP_SEG(bp);
regs.x.di = FP_OFF(bp);
Bpqinfo.contcnt++;
break;
case BPQ_BEACON:
regs.x.dx = 1;
sregs.es = FP_SEG(bp);
regs.x.si = FP_OFF(bp);
regs.x.cx = flag;
case BPQ_STATE:
case BPQ_ACKSTATE:
case BPQ_TIME:
Bpqinfo.contcnt++;
break;
default:
return -1;
}
int86x(Bpqinfo.vec,®s,®s,&sregs);
switch(command){
case BPQ_USERCALL:
bp[10] = '\0';
case BPQ_TIME:
rval = regs.x.ax;
break;
case BPQ_PACLEN:
case BPQ_RECVQUE:
rval = regs.x.bx;
break;
case BPQ_RECV:
case BPQ_RX:
case BPQ_UNACK:
rval = regs.x.cx;
break;
case BPQ_BUF:
rval = regs.x.dx;
break;
case BPQ_MAXFR:
rval = max(regs.x.cx,regs.x.dx);
break;
case BPQ_STATE:
rval = (regs.x.dx << 8) | regs.x.cx;
break;
default:
rval = 0;
}
return rval;
}
#endif /* BPQ */